var x = 25;
var y = 250;
var dx = 4.5;
var dy = -10;
var ctx;
var WIDTH;
var HEIGHT;
var paddlex;
var paddleh = 10;
var paddlew = 75;
var rightDown = false;
var leftDown = false;
var breakoutCanvasMinX = 0;
var breakoutCanvasMaxX = 0;
var intervalId = 0;
var bricks;
var brickPowerUps;
var powerUpActive = 0;
var powerUpX = 0;
var powerUpY = 0;
var currentPowerUps = [];
var BRICKWIDTH = 99;
var BRICKHEIGHT = 20;
var PADDING = -4;
var score = 0;
var POWERUP_PROBABILITY = 40;
var COLUMNS = 6;
var numrows;
var numcols;
var BRICKTYPES = 6;
var backgroundImage;
var level;

// sound effects //
var hitEffect = new Audio("hit.mp3");
var destroyEffect = new Audio("destroy.mp3");
var lostLifeEffect = new Audio("lostlife.mp3");
var gameOverEffect = new Audio("gameover.mp3");
var powerUpEffect = new Audio("comet.mp3");
var xBounceEffect = new Audio("xbounce.mp3");
var yBounceEffect = new Audio("ybounce.mp3");
var nextLevelEffect = new Audio("nextlevel.mp3");

// images //
var paddle = new Image();
paddle.src = "paddle.png";
var ball = new Image();
ball.src = "ball.png";
var livesImage = new Image();
livesImage.src = "vita.png";
var powerUpImage = new Image();
powerUpImage.src = "comet.png";

// background images //
var backgroundImages = new Array();
backgroundImages[0] = new Image();
backgroundImages[0].src = "galaxy0.jpg";
backgroundImages[1] = new Image();
backgroundImages[1].src = "galaxy1.jpg";
backgroundImages[2] = new Image();
backgroundImages[2].src = "galaxy2.jpg";
backgroundImages[3] = new Image();
backgroundImages[3].src = "galaxy3.jpg";
backgroundImages[4] = new Image();
backgroundImages[4].src = "galaxy4.jpg";
backgroundImages[5] = new Image();
backgroundImages[5].src = "galaxy5.jpg";

// brick images //
var brickImages = new Array();
brickImages[0] = new Image();
brickImages[0].src = "brick0.png";
brickImages[1] = new Image();
brickImages[1].src = "brick1.png";
brickImages[2] = new Image();
brickImages[2].src = "brick2.png";
brickImages[3] = new Image();
brickImages[3].src = "brick3.png";
brickImages[4] = new Image();
brickImages[4].src = "brick4.png";
brickImages[5] = new Image();
brickImages[5].src = "brick5.png";

var initialLives = 3;
var lives = initialLives;
var livesSpacing = 25;

function init() {
    initLevelData();
    level = 1;
    ctx = $('#breakoutCanvas')[0].getContext("2d");
    WIDTH = $("#breakoutCanvas").width();
    HEIGHT = $("#breakoutCanvas").height();
    paddlex = WIDTH / 2;
    breakoutCanvasMinX = $("#breakoutCanvas").offset().left;
    breakoutCanvasMaxX = breakoutCanvasMinX + WIDTH;
    intervalId = setInterval(draw, 30);

    return intervalId;
}

function initLevelData() {
    backgroundImage = Math.floor(Math.random() * 6);
    
    numrows = Math.floor(Math.random() * 12) + 1;
    numcols = 6;

    bricks = new Array(numrows);
    for (i = 0; i < numrows; i++) {
	bricks[i] = new Array(numcols);
	for (j = 0; j < numcols; j++) {
	    bricks[i][j] = Math.round(Math.random());
	}
    }
}

function restart() {
    x = 25;
    y = 250;
    dy *= -1;
    drawLives();
    lostLifeEffect.play();
}

function restartGame() {
    $('#endGame').hide();
    init();
    x = 25;
    y = 250;
	dx = 4.5;
	dy = -10;
    score = 0;
    lives = initialLives;
    initbricks();
    initLevelData();
    clearInterval(intervalId);
    intervalId = setInterval(draw, 30);
}

function gameOver() {
    gameOverEffect.play();
    drawLives();
    $('#endGameScore').html(score);
    $('#endGame').show();
    clearInterval(intervalId);
}

function rect(x,y,w,h) {
    ctx.beginPath();
    ctx.rect(x,y,w,h);
    ctx.closePath();
    ctx.fill();
}

function clear() {
    ctx.clearRect(0, 0, WIDTH, HEIGHT);
    rect(0,0,WIDTH,HEIGHT);
}

function onKeyDown(evt) {
    if (evt.keyCode == 39) {
	rightDown = true;
    } else if (evt.keyCode == 37) {
	leftDown = true;
    }
}

function onKeyUp(evt) {
    if (evt.keyCode == 39) {
	rightDown = false;
    } else if (evt.keyCode == 37) {
	leftDown = false;
    }
}

$(document).keydown(onKeyDown);
$(document).keyup(onKeyUp);

function onMouseMove(evt) {
    if (evt.pageX > breakoutCanvasMinX && evt.pageX < breakoutCanvasMaxX) {
	paddlex = Math.max(evt.pageX - breakoutCanvasMinX - (paddlew/2), 0);
	paddlex = Math.min(WIDTH - paddlew, paddlex);
    }
}

$(document).mousemove(onMouseMove);

function initbricks() {
    brickPowerUps = $.extend(true, [], bricks);
    for (i = 0; i < numrows; i++) {
	for (j = 0; j < numcols; j++) {
	    brickPowerUps[i][j] = ( ( (99 * Math.random()) < POWERUP_PROBABILITY ) ? 1 : 0);
	}
    }
}

function drawbricks() {
    for (i = 0; i < numrows; i++) {
    	for (j = 0; j < numcols; j++) {
    	    if (bricks[i][j]) {
    			ctx.drawImage(brickImages[i % BRICKTYPES], j * (BRICKWIDTH + PADDING) + PADDING + 5, i * (BRICKHEIGHT + PADDING) + PADDING + 5, BRICKWIDTH-5, BRICKHEIGHT-5);
    	    }
    	}
    }
}

function drawLives() {
    for (i = 0; i < lives; i++) {
	ctx.drawImage(livesImage, 10 + i * livesSpacing, 10);
    }
    if (lives == 0) {
	gameOverScreen();
    }
}

function throwPowerUp() {
    if (!powerUpActive) {
	powerUpX = x;
	powerUpY = y;
	powerUpActive = 1;
    }
}

function catchPowerUp() {
    score += 10;
    powerUpX = -10;
    powerUpY = -10;
    powerUpActive = 0;
    powerUpEffect.play();
    applyPowerUp();
}

function missPowerUp() {
    powerUpX = -10;
    powerUpY = -10;
    powerUpActive = 0;
	//console.log('MISSED POWER UP!');
}

function applyPowerUp() {
    while (true) {
	var type = Math.floor(Math.random()*3);
	if ($.inArray(type, currentPowerUps) != -1) {
	    //console.log('this powerup is already active');
	} else {
	    break;
	}
    }

    switch (type) {
    case 0:
	lives += 1;
	$('#powerUp').html("Extra Life!");
	$('#powerUp').show();
	setTimeout(function() {
	    $('#powerUp').hide();
	}, 3000);
	break;
    case 1:
	paddlew *= 2;
	$('#powerUp').html("Extend Width!");
	$('#powerUp').show();
	setTimeout(function() {
	    paddlew /= 2;
	    currentPowerUps.splice(currentPowerUps.indexOf(type), 1);
	    $('#powerUp').hide();
	}, 5000);

	break;
    case 2:
	dx /= 2;
	dy /= 2;
	$('#powerUp').html("Decrease Speed!");
	$('#powerUp').show();
	setTimeout(function() {
	    dx *= 2;
	    dy *= 2;
	    currentPowerUps.splice(currentPowerUps.indexOf(type), 1);
	    $('#powerUp').hide();
	}, 5000);

	break;
    }

    currentPowerUps.push(type);
}

function drawPowerUp() {
    if (powerUpActive) {
	ctx.drawImage(powerUpImage, powerUpX, powerUpY, 30, 30);
	powerUpX += Math.floor(Math.random()*5)-2;
	powerUpY += 5;
    }
}

function isZero(n) {
    return (n == 0);
}

function isZeroesArray(a) {
    for (i = 0; i < a.length; i++) {
	for (j = 0; j < a[i].length; j++) {
	    if (a[i][j] != 0) {
		return false;
	    }
	}
    }
    return true;
}

function gameOverScreen() {
    clear();
    ctx.drawImage(backgroundImages[backgroundImage], 0, 0);
    ctx.drawImage(paddle, paddlex, HEIGHT - paddleh);
    drawbricks();
}

function nextLevel() {
    nextLevelEffect.play();
    initLevelData();
    score += 100 * level;
    level += 1;
    initbricks();
    var x = 25;
    var y = 250;
	dx *= 1.5;
	dy *= 1.5;
	clearInterval(intervalId);
	intervalId = setInterval(draw, 30);
}